/*
 *  ArcPlatform.m
 *  pogostick
 *
 *  Created by daddy (chuck@kollar.com) on 9/11/09.
 *  Copyright 2009 Charles P. Kollar All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ArcPlatform.h"


@implementation ArcPlatform

@synthesize offsetMultiple;
@synthesize center;

-(id)initInSpace: (cpSpace *)sp staticBody:(cpBody *)sb identifier:(NSString *)ident atPosition:(cpVect)p size:(cpVect)sz
{
    return [self initInSpace: sp staticBody: sb identifier: ident atPosition: p size: sz wallWidth: 5.0f];
}

-(id)initInSpace: (cpSpace *)sp staticBody:(cpBody *)sb identifier:(NSString *)ident atPosition:(cpVect)p size:(cpVect)sz wallWidth:(cpFloat)ww
{
	if (self = [super init]) {
        identifier = ident;
		space = sp;
		staticBody = sb;
        center = p;
		wall_width = ww;
		box_width = sz.x * 0.25f;
		offsetMultiple = 1;
		
		cpVect verts[] = {
			cpv(-box_width,-wall_width),
			cpv(-box_width,wall_width),
			cpv(box_width,wall_width),
			cpv(box_width,-wall_width)
		};
		platformBody = cpBodyNew(PLATFORM_MASS, INFINITY);
		platformBody->p = center;
		//platformBody->velocity_func = arcPlatformBodyUpdateVelocity;
		cpSpaceAddBody(space, platformBody);
		shape = cpPolyShapeNew(platformBody, (sizeof(verts)/sizeof(cpVect)), verts, cpvzero);
		shape->e = 0.0; shape->u = 1.0;
		shape->collision_type = kColl_Ground;
		cpSpaceAddShape(space, shape); 
		// these joints hold the platform in an arc
		joint = cpPinJointNew(staticBody, platformBody, cpv(center.x,center.y+box_width*offsetMultiple), cpvzero);
		cpSpaceAddConstraint(space, joint);
	}
	return self;
}

-(void) dealloc {
    //cpConstraintFree(joint);
    //cpShapeFree(shape);
	//cpBodyFree(platformBody);
    
    [super dealloc];
}

-(void)performActions {
    cpVect pos = platformBody->p;// location of the platform body
    
    // when the platform reaches the top of the arc, reverse it...
    // where the joint attaches to the staticBody...
    cpPinJoint *j = (cpPinJoint *)joint;
    // attachment to the platform (not the staticSpace!!!)
    cpVect attach = j->anchr1;
    cpVect impNormal = cpvsub(attach, pos);
    if (pos.y >= attach.y) {
        direction = -1; // clockwise (down)
        platformBody->v = cpv(-impNormal.y, impNormal.x); platformBody->w = 0.0f;
    } else if (pos.x <= attach.x) {
        direction = 1; // anti-clockwise (up)
        platformBody->v = cpv(impNormal.y, -impNormal.x); platformBody->w = 0.0f;
    }
    // newdx = -dy and newdy=dx for clockwise, and newdx = dy and newdy = -dx for anti-clockwise.
    cpVect imp = (direction == -1) ? cpv(-impNormal.y, impNormal.x) : cpv(impNormal.y, -impNormal.x);
    //printf("pos %f,%f  attach %f,%f  impNormal %f,%f  imp %f,%f\n", pos.x, pos.y, attach.x, attach.y, impNormal.x, impNormal.y, imp.x, imp.y);
    // apply a force normal to the link in the direction indicated.
    cpBodyApplyImpulse(platformBody, cpvclamp(imp, 6.0f), cpvzero);
}

@end
